package plugins.imageViewer;


import javax.imageio.ImageIO;


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import java.util.ArrayList;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Toolkit;

import java.awt.*;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import plugins.jTreeFolder.NodeWithFile;
/**
 * La classe Picture permet de créér une visionneuse d'images à partir d'une liste
 * d'images disponibles.
 *
 */
public class Picture implements ActionListener 
{
    private BufferedImage image;
    protected ArrayList<File> photosDisponibles = new ArrayList<File> ();
    private JFrame f;

    int indexCourant,indexAffiche;
    private JLabel label;
   
    private JButton suivant,precedent;
    private JPanel menuBoutons;

    private JLabel nbPhotos;
 
    private Dimension d;

    
    public Picture(int w, int h) {
        image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        indexCourant = 0;
        indexAffiche =1;
    }
    /** Retourne la nombre d'images disponibles dans le repertoire courant
     * 
     * @return int nombre d'images disponibles 
     */
    public int getNbPhotosDisponibles()
    {
    	return photosDisponibles.size();
    }
    
    
    public Picture(String filename) {
        try { image = ImageIO.read(new File(filename)); }
        catch(IOException e) {
            e.printStackTrace();
            throw new RuntimeException("Ouverture du fichier impossible: " + filename);
        }
        if (image == null)
            throw new RuntimeException("Fichier invalide: " + filename);
    }

    /**
     * Constructeur de la classe Picture  
     * 
     * @param file
     *            le fichier à ouvrir
     * 
     * 
     */
    public Picture(File file) {
        photosDisponibles.add(file);
        indexCourant = 0;
        indexAffiche=1;
       
    }

    /**
     * Méthode permettant de récupérer l'image à afficher dans un JLabel
     * 
     * @return JLabel Label contenant l'image à afficher
     */
    public JLabel getJLabel() {
        if (image == null) return null;         
        //BufferedImage i = scale(image, 0.5);
        ImageIcon icon = new ImageIcon(image);
        label = new JLabel(icon);
        return label ;
    }
    
    /**
     * Méthode de redimensionnement proportionnel d'une image
     * @param bImage Image à redimensionner
     * @param factor Facteur d'agrandissement ou de réduction de l'image
     * @return BufferedImage L'image redimensionnée
     */
    public static BufferedImage scale(BufferedImage bImage, double factor) {
        int destWidth=(int) (bImage.getWidth() * factor);
        int destHeight=(int) (bImage.getHeight() * factor);
        //créer l'image de destination
        GraphicsConfiguration configuration = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
        BufferedImage bImageNew = configuration.createCompatibleImage(destWidth, destHeight);
        Graphics2D graphics = bImageNew.createGraphics();
        graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
        //dessiner l'image de destination
        graphics.drawImage(bImage, 0, 0, destWidth, destHeight, 0, 0, bImage.getWidth(), bImage.getHeight(), null);
        graphics.dispose();

        return bImageNew;
    }

    /** Affiche des boutons de navigation "Suivant" et "Précédent" permettant de faire défiler les images
     * 
     * @param photosDisponibles Liste des photos disponibles dans le repertoire courant
     */
    public void navigationBoutons(ArrayList<File> photosDisponibles)
    {
    	menuBoutons    = new JPanel();
    	suivant = new JButton("Suivant");
    	precedent = new JButton("Précédent");  	
    	this.photosDisponibles.addAll(photosDisponibles);
   
    	
    	
    	suivant.addMouseListener(new MouseListener() {
			
			@Override
			public void mouseReleased(MouseEvent arg0) {}
			
			@Override
			public void mousePressed(MouseEvent arg0) {}
			
			@Override
			public void mouseExited(MouseEvent arg0) {}
			
			@Override
			public void mouseEntered(MouseEvent arg0) {}
			
			@Override
			public void mouseClicked(MouseEvent arg0) {
				if(indexCourant == (getNbPhotosDisponibles()-1))
				{
					indexCourant = 0;
					indexAffiche = 1;
					
					getImageByIndex(indexCourant);
				}
				else
				{
					indexCourant++;
					indexAffiche++;
					
					getImageByIndex(indexCourant);
					
				}
				
				}
		});
    	
    	precedent.addMouseListener(new MouseListener() {
			
			@Override
			public void mouseReleased(MouseEvent arg0) {}
			
			@Override
			public void mousePressed(MouseEvent arg0) {}
			
			@Override
			public void mouseExited(MouseEvent arg0) {}
			
			@Override
			public void mouseEntered(MouseEvent arg0) {}
			
			/** Precedent*/
			@Override
			public void mouseClicked(MouseEvent arg0) {
				if(indexCourant == 0)
				{
					indexCourant = (getNbPhotosDisponibles()-1);
					indexAffiche = getNbPhotosDisponibles();
					getImageByIndex(indexCourant);
				}
				else
				{
					indexCourant--;
					indexAffiche--;
					getImageByIndex(indexCourant);
				}
				
			}
			
		});
    	
   
    }
    
    /**
     * 
     * @return
     */
    public JFrame show() {

        if (f == null) 
        {
            f = new JFrame();
            nbPhotos = new JLabel("Photo : "+ (indexAffiche) +"/"+getNbPhotosDisponibles());
            //f.setLocationRelativeTo(null);
            try {
				image = ImageIO.read(photosDisponibles.get(indexCourant));
			} catch (IOException e) {
				e.printStackTrace();
	            throw new RuntimeException("Ouverture du fichier impossible: " + photosDisponibles.get(indexCourant));
			}
			
			/* si limage depasse le cadre, on la recoupe en 2) */
			
			
            d = Toolkit.getDefaultToolkit().getScreenSize();
    		f.setBounds((d.width/2)-350, (d.height/2)-300, 800, 600);          
    		f.add(menuBoutons,BorderLayout.SOUTH);
    		
    		while(image.getWidth()>800 || image.getHeight()>600)
    		{
    			image = scale(image,0.5);
    		} 
    		
            menuBoutons.add(precedent,BorderLayout.EAST);
            menuBoutons.add(suivant,BorderLayout.WEST);
            menuBoutons.add(nbPhotos,BorderLayout.EAST);
            menuBoutons.setVisible(true);
            menuBoutons.setBackground(Color.gray);
    		f.add(getJLabel());
    		
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            f.setTitle("Visionneuse d'images");
            f.setResizable(false);
            
            f.setVisible(true);
        }

        f.repaint();
        return f;
    }
    /** Construit la fenêtre avec l'image correspond à l'index passé en paramètre.
     * 
     * @param indexCourant Index de l'image à récupérer
     */
    public void getImageByIndex(int indexCourant) {
    	for(int i=0;i<photosDisponibles.size();i++)
		{
			photosDisponibles.get(i);
		}
        if (f != null) 
        {
        	f.remove(label);
        	menuBoutons.remove(nbPhotos);
        	nbPhotos = new JLabel("Photo : "+ (indexAffiche) +"/"+getNbPhotosDisponibles());
            try {
				image = ImageIO.read(photosDisponibles.get(indexCourant));
			} catch (IOException e) {
				e.printStackTrace();
	            throw new RuntimeException("Ouverture du fichier impossible: " + photosDisponibles.get(indexCourant));
			}
			d = Toolkit.getDefaultToolkit().getScreenSize();
	    		f.setBounds((d.width/2)-350, (d.height/2)-300, 800, 600);          
	    		f.add(menuBoutons,BorderLayout.SOUTH);
	    		while(image.getWidth()>800 || image.getHeight()>600)
	    		{
	    			image = scale(image,0.5);
	    		} 
    		f.add(getJLabel());
    		menuBoutons.add(nbPhotos,BorderLayout.WEST);
    		 
    		f.setResizable(false);
    		
            f.setVisible(true);     
        }

        // draw
        f.repaint();
    }
    /** Retourne la hauteur de l'image consultée
     * 
     * @return int La hauteur de l'image consultée 
     */
    public int height() { return image.getHeight(null); }
    
    /** Retourne la largeur de l'image consultée
     * 
     * @return int La largeur de l'image consultée 
     */
    public int width()  { return image.getWidth(null);  }

   
    public Color getColor(int i, int j) {
        return new Color(image.getRGB(i, j));
    }

    public int getGray(int i, int j) {
        Color color = getColor(i, j);
        int r = color.getRed();
        int g = color.getGreen();
        int b = color.getBlue();
        int luminance = (int) (0.299*r + 0.587*g + 0.114*b); 
        return luminance;
    }


    public void setGray(int i, int j, int c) {
        Color color = new Color(c, c, c);
        setColor(i, j, color);
    }


    public void setColor(int i, int j, Color c) {
        image.setRGB(i, j, c.getRGB());
    }


    public void save(String filename) { save(new File(filename)); }


    public void save(File file) {
        String filename = file.getName();
        String suffix = filename.substring(filename.lastIndexOf('.') + 1);
        try { ImageIO.write(image, suffix, file); }
        catch (IOException e) { e.printStackTrace(); }
    }
    
    public static void main(String args[]) {
        Picture pic = new Picture(args[0]);
        pic.show();
    }
    @Override
	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
		
	}
   
}